package com.labofjet.spring.data;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;

/**
 * 需要使用原生SQL的repository的父类
 * 
 * @author jyzjyz12@163.com
 * 
 */
@SuppressWarnings("rawtypes")
public class NativeSQLRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements
        NativeSQLRepository<T, ID> {
    private final EntityManager entityManager;

    public NativeSQLRepositoryImpl(JpaEntityInformation entityInformation, EntityManager entityManager) {
        super(entityInformation, entityManager);
        this.entityManager = entityManager;
    }

    @Override
    public List executeNativeQuerySQLReturnObject(String namedQuery, Map<String, Object> paramMap, Class<?> targetClass) {
        EntityManager em = entityManager;
        Query query = em.createNativeQuery(namedQuery);
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.aliasToBean(targetClass));
        if (paramMap != null) {
            for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
                query.setParameter(entry.getKey(), entry.getValue());
            }
        }
        return query.getResultList();
    }

    @Override
    public List executeNativeQuerySQLReturnList(String namedQuery, Map<String, Object> paramMap) {
        EntityManager em = entityManager;
        Query query = em.createNativeQuery(namedQuery);
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.TO_LIST);
        if (paramMap != null) {
            for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
                query.setParameter(entry.getKey(), entry.getValue());
            }
        }
        return query.getResultList();
    }

    @Override
    public List executeNativeQuerySQLReturnMap(String namedQuery, Map<String, Object> paramMap) {
        EntityManager em = entityManager;
        Query query = em.createNativeQuery(namedQuery);
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        if (paramMap != null) {
            for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
                query.setParameter(entry.getKey(), entry.getValue());
            }
        }
        return query.getResultList();
    }

    @Override
    public int executeUpdateSQL(String sql, Map<String, Object> paramMap) {
        EntityManager em = entityManager;
        Query query = em.createNativeQuery(sql);
        if (paramMap != null) {
            for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
                query.setParameter(entry.getKey(), entry.getValue());
            }
        }
        return query.executeUpdate();
    }
}
